#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <pthread.h>
#include "shmem.h"
#include "msg_queue_peer.h"

// 共享内存数据结构
typedef union val_t
{
    int b_val;
    int i_val;
    float f_val;
} val_t;

struct std_node
{
    int key;
    int type;
    int dev_type;
    val_t old_val;
    val_t new_val;
    int ret;
};

// 全局变量：客户端连接的文件描述符（线程间共享）
static int g_acceptfd = -1;
// 互斥锁：保护全局变量的线程安全
static pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;

// 按行分割字符串
int splitLines(char *buf, char **lines, int maxLines)
{
    int lineCount = 0;
    char *token = strtok(buf, "\n");
    while (token != NULL && lineCount < maxLines)
    {
        lines[lineCount++] = token;
        token = strtok(NULL, "\n");
    }
    return lineCount;
}

// 将字符串"ON"/"OFF"转换为布尔值(1/0)
int stringToBool(char *str)
{
    return (strcmp(str, "ON") == 0 || strcmp(str, "ON ") == 0) ? 1 : 0;
}

// 线程函数：处理消息队列，直接用strcmp匹配完整字符串
void *msg_queue_thread(void *arg)
{
    char buf[1024];
    while (1)
    {
        // 从消息队列接收消息
        int ret = msg_queue_recv("32control_queue", buf, sizeof(buf) - 1, 0, 1);
        if (ret > 0)
        {
           
            printf("从消息队列收到消息: %s\n", buf);

            // 定义要发送的控制指令（默认空）
            const char *control_msg = NULL;

            // 直接匹配完整字符串（304-308的开/关指令）
            if (strcmp(buf, "CTRL:304:1") == 0)
                control_msg = "DRY_ON";
            else if (strcmp(buf, "CTRL:304:0") == 0)
                control_msg = "DRY_OFF";
            else if (strcmp(buf, "CTRL:305:1") == 0)
                control_msg = "MOISY_ON";
            else if (strcmp(buf, "CTRL:305:0") == 0)
                control_msg = "MOISY_OFF";
            else if (strcmp(buf, "CTRL:306:1") == 0)
                control_msg = "COOLER_ON";
            else if (strcmp(buf, "CTRL:306:0") == 0)
                control_msg = "COOLER_OFF";
            else if (strcmp(buf, "CTRL:307:1") == 0)
                control_msg = "HEATER_ON";
            else if (strcmp(buf, "CTRL:307:0") == 0)
                control_msg = "HEATER_OFF";
            else if (strcmp(buf, "CTRL:308:1") == 0)
                control_msg = "BUZZER_ON";
            else if (strcmp(buf, "CTRL:308:0") == 0)
                control_msg = "BUZZER_OFF";
            else
                printf("未知指令: %s，忽略\n", buf);

            // 如果匹配到有效指令，发送给客户端
            if (control_msg != NULL)
            {
                pthread_mutex_lock(&g_mutex);
                int client_fd = g_acceptfd;
                pthread_mutex_unlock(&g_mutex);

                if (client_fd != -1)
                {
                    // // 先发送MANUAL_MODE
                    // if (send(client_fd, "MANUAL_MODE", strlen("MANUAL_MODE"), 0) < 0)
                    //     perror("发送MANUAL_MODE失败");
                    // else
                    //     printf("已发送: MANUAL_MODE\n");
                    // 再发送对应控制指令
                    if (send(client_fd, control_msg, strlen(control_msg), 0) < 0)
                        perror("发送控制指令失败");
                    else
                        printf("已发送控制指令: %s\n", control_msg);
                }
                else
                {
                    printf("客户端未连接，无法发送指令\n");
                }
            }
        }
        else if (ret < 0)
        {
            perror("消息队列读取错误");
            sleep(1);
        }
    }
    return NULL;
}

int main(int argc, char const *argv[])
{
    int ret = 0;
    char buf[1024] = {0};

    // 检查端口参数
    if (argc != 2)
    {
        fprintf(stderr, "使用方法: %s <端口号>\n", argv[0]);
        return -1;
    }

    // 初始化共享内存
    struct shm_param shm_para;
    const char *shm_name = "test";
    size_t shm_size = 2048;
    if (shm_init(&shm_para, shm_name, shm_size) != 0)
    {
        fprintf(stderr, "共享内存初始化失败\n");
        return -1;
    }
    void *shm_addr = shm_getaddr(&shm_para);
    if (shm_addr == NULL)
    {
        fprintf(stderr, "获取共享内存地址失败\n");
        shm_del(&shm_para);
        return -1;
    }
    printf("共享内存初始化成功，大小: %zu 字节\n", shm_size);
    struct std_node *shm_nodes = (struct std_node *)shm_addr;
    int max_nodes = shm_size / sizeof(struct std_node);

    // 创建TCP socket
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0)
    {
        perror("socket创建失败");
        shm_del(&shm_para);
        return -1;
    }
    printf("sockfd: %d\n", sockfd);

    // 设置端口复用
    int opt = 1;
    if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0)
    {
        perror("setsockopt失败");
        close(sockfd);
        shm_del(&shm_para);
        return -1;
    }

    // 绑定地址和端口
    struct sockaddr_in saddr, caddr;
    saddr.sin_family = AF_INET;
    saddr.sin_port = htons(atoi(argv[1]));
    saddr.sin_addr.s_addr = INADDR_ANY;
    socklen_t len = sizeof(caddr);
    if (bind(sockfd, (struct sockaddr *)&saddr, sizeof(saddr)) != 0)
    {
        perror("bind失败");
        close(sockfd);
        shm_del(&shm_para);
        return -1;
    }
    printf("bind成功\n");

    // 监听连接
    if (listen(sockfd, 6) != 0)
    {
        perror("listen失败");
        close(sockfd);
        shm_del(&shm_para);
        return -1;
    }
    printf("监听中...\n");

    // 创建消息队列处理线程
    pthread_t msg_thread;
    if (pthread_create(&msg_thread, NULL, msg_queue_thread, NULL) != 0)
    {
        perror("创建消息线程失败");
        close(sockfd);
        shm_del(&shm_para);
        return -1;
    }
    pthread_detach(msg_thread); // 线程后台运行

    // 主线程：处理客户端连接和数据接收
    while (1)
    {
        int acceptfd = accept(sockfd, (struct sockaddr *)&caddr, &len);
        if (acceptfd < 0)
        {
            perror("accept失败");
            continue;
        }
        printf("\n新客户端连接: acceptfd=%d\n", acceptfd);
        printf("客户端信息: IP=%s, port=%d\n",
               inet_ntoa(caddr.sin_addr), ntohs(caddr.sin_port));

        // 更新全局客户端连接（加锁保证线程安全）
        pthread_mutex_lock(&g_mutex);
        g_acceptfd = acceptfd;
        pthread_mutex_unlock(&g_mutex);

        // 循环接收客户端数据
        while (1)
        {
            memset(buf, 0, sizeof(buf));
            ret = recv(acceptfd, buf, sizeof(buf) - 1, 0);
            if (ret < 0)
            {
                perror("接收数据失败");
                break;
            }
            else if (ret == 0)
            {
                printf("客户端已断开连接\n");
                break;
            }
            buf[ret] = '\0';
            printf("收到客户端消息: %s\n", buf);

            // 按行分割数据并更新共享内存
            char *lines[32] = {0};
            int lineCount = splitLines(buf, lines, 32);
            for (int i = 0; i < lineCount; i++)
            {
                char *line = lines[i];
                float value_f;
                char status[8];

                // 处理温度和湿度
                if (strstr(line, "温度:") && strstr(line, "湿度:"))
                {
                    float temp, hum;
                    if (sscanf(line, "温度: %f°C 湿度: %f%%", &temp, &hum) == 2)
                    {
                        for (int j = 0; j < max_nodes; j++)
                        {
                            if (shm_nodes[j].key == 301)
                            {
                                shm_nodes[j].old_val = shm_nodes[j].new_val;
                                shm_nodes[j].new_val.f_val = temp;
                                shm_nodes[j].ret = 0;
                            }
                            if (shm_nodes[j].key == 302)
                            {
                                shm_nodes[j].old_val = shm_nodes[j].new_val;
                                shm_nodes[j].new_val.f_val = hum;
                                shm_nodes[j].ret = 0;
                            }
                        }
                    }
                    continue;
                }

                // 处理电压（key=303）
                if (strstr(line, "电压:"))
                {
                    if (sscanf(line, "电压: %fV", &value_f) == 1)
                    {
                        for (int j = 0; j < max_nodes; j++)
                        {
                            if (shm_nodes[j].key == 303)
                            {
                                shm_nodes[j].old_val = shm_nodes[j].new_val;
                                shm_nodes[j].new_val.f_val = value_f;
                                shm_nodes[j].ret = 0;
                                break;
                            }
                        }
                    }
                    continue;
                }

                // 处理设备开关状态（304-308）
                int target_key = -1;
                if (strstr(line, "除湿器:"))
                    target_key = 304;
                else if (strstr(line, "加湿器:"))
                    target_key = 305;
                else if (strstr(line, "制冷器状态:"))
                    target_key = 306;
                else if (strstr(line, "加热器状态:"))
                    target_key = 307;
                else if (strstr(line, "蜂鸣器:"))
                    target_key = 308;

                if (target_key != -1)
                {
                    char format[64];
                    snprintf(format, sizeof(format), "%%*[^:]: %%7s");
                    if (sscanf(line, format, status) == 1)
                    {
                        int bool_val = stringToBool(status);
                        for (int j = 0; j < max_nodes; j++)
                        {
                            if (shm_nodes[j].key == target_key)
                            {
                                shm_nodes[j].old_val = shm_nodes[j].new_val;
                                shm_nodes[j].new_val.b_val = bool_val;
                                shm_nodes[j].ret = 0;
                                break;
                            }
                        }
                    }
                }
            }

            printf("已更新共享内存（301-308）\n");
            // 打印更新结果
            printf("\n更新后的数据：\n");
            for (int j = 0; j < max_nodes; j++)
            {
                if (shm_nodes[j].key >= 301 && shm_nodes[j].key <= 308 && shm_nodes[j].ret == 0)
                {
                    switch (shm_nodes[j].key)
                    {
                    case 301:
                        printf("温度：%.2f°C\n", shm_nodes[j].new_val.f_val);
                        break;
                    case 302:
                        printf("湿度：%.1f%%\n", shm_nodes[j].new_val.f_val);
                        break;
                    case 303:
                        printf("电压：%.2fV\n", shm_nodes[j].new_val.f_val);
                        break;
                    case 304:
                        printf("除湿器：%s\n", shm_nodes[j].new_val.b_val ? "ON" : "OFF");
                        break;
                    case 305:
                        printf("加湿器：%s\n", shm_nodes[j].new_val.b_val ? "ON" : "OFF");
                        break;
                    case 306:
                        printf("制冷器：%s\n", shm_nodes[j].new_val.b_val ? "ON" : "OFF");
                        break;
                    case 307:
                        printf("加热器：%s\n", shm_nodes[j].new_val.b_val ? "ON" : "OFF");
                        break;
                    case 308:
                        printf("蜂鸣器：%s\n", shm_nodes[j].new_val.b_val ? "ON" : "OFF");
                        break;
                    }
                }
            }
        }

        // 客户端断开，更新全局连接状态
        close(acceptfd);
        pthread_mutex_lock(&g_mutex);
        g_acceptfd = -1;
        pthread_mutex_unlock(&g_mutex);
        printf("已关闭客户端连接（acceptfd=%d）\n", acceptfd);
    }

    // 清理资源（实际不会执行）
    close(sockfd);
    shm_del(&shm_para);
    return 0;
}